namespace Asmex.FileViewer
{
    using System;
    using System.IO;

    public class TableCell
    {
        private object _data;
        private uint _rawData;
        private Types _type;

        public TableCell(Types type, BinaryReader reader, MDTables helper)
        {
            this._type = type;
            try
            {
                if (type == Types.UInt16)
                {
                    this._rawData = reader.ReadUInt16();
                }
                if (type == Types.UInt32)
                {
                    this._rawData = reader.ReadUInt32();
                }
                if (type == Types.String)
                {
                    this._rawData = (helper.GetStringIndexSize() == 2) ? reader.ReadUInt16() : reader.ReadUInt32();
                }
                if (type == Types.Guid)
                {
                    this._rawData = (helper.GetGuidIndexSize() == 2) ? reader.ReadUInt16() : reader.ReadUInt32();
                }
                if (type == Types.Blob)
                {
                    this._rawData = (helper.GetBlobIndexSize() == 2) ? reader.ReadUInt16() : reader.ReadUInt32();
                }
                if (type < Types.TypeDefOrRef)
                {
                    Table table = helper.GetTable(type);
                    this._rawData = (uint) ((((uint) type) << 0x18) | ((table.Count < 0x10000) ? reader.ReadUInt16() : reader.ReadUInt32()));
                }
                else if (type < Types.UInt16)
                {
                    int num = (helper.SizeOfType(type) == 2) ? reader.ReadUInt16() : reader.ReadInt32();
                    Types[] typesArray = helper.CodedTokenTypes(type);
                    int index = num & ~(((int) (-1)) << helper.CodedTokenBits(typesArray.Length));
                    int num3 = num >> helper.CodedTokenBits(typesArray.Length);
                    int num4 = helper.ToToken(typesArray[index], num3 - 1);
                    this._rawData = (uint) num4;
                }
                this._data = this.CreateData(helper);
            }
            catch (Exception)
            {
                this._type = Types.String;
                this._data = string.Concat(new object[] { "Unreadable cell: ", type, " ", this._rawData });
            }
        }

        private object CreateData(MDTables helper)
        {
            switch (this._type)
            {
                case Types.UInt16:
                    return (ushort) this._rawData;

                case Types.UInt32:
                    return this._rawData;

                case Types.String:
                    return helper.GetString((int) this._rawData);

                case Types.Blob:
                    return helper.GetBlob((int) this._rawData);

                case Types.Guid:
                    return helper.GetGuid((int) this._rawData);
            }
            if (this._type < Types.TypeDefOrRef)
            {
                return new RID(this._type, this._rawData);
            }
            return new CodedToken(this._type, this._rawData, helper);
        }

        public object Data
        {
            get
            {
                return this._data;
            }
        }

        public uint RawData
        {
            get
            {
                return this._rawData;
            }
        }
    }
}
